#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <string>
#include <QCoreApplication>
#include <QHash>
#include "settings.h"

using namespace std;

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    int m_argc;
    char** m_argv = nullptr;
    Settings m_CurrentSet;
    const QString m_basePath = QCoreApplication::applicationDirPath();
    const QString m_settingPath = QCoreApplication::applicationDirPath() + "/Settings";
    QHash<QString, Settings::Pattern> m_enumMap = { {"CHESSBOARD", Settings::CHESSBOARD},
                                                                 {"CIRCLES_GRID", Settings::CIRCLES_GRID},
                                                                 {"ASYMMETRIC_CIRCLES_GRID", Settings::ASYMMETRIC_CIRCLES_GRID},
                                                                 {"", Settings::NOT_EXISTING} };
    QHash<Settings::Pattern, QString> m_strMap = { {Settings::CHESSBOARD, "CHESSBOARD"},
                                                                  {Settings::CIRCLES_GRID, "CIRCLES_GRID"},
                                                                  {Settings::ASYMMETRIC_CIRCLES_GRID, "ASYMMETRIC_CIRCLES_GRID"},
                                                                  {Settings::NOT_EXISTING, ""} };

public:
    MainWindow(int argc, char** argv, QWidget *parent = nullptr);
    ~MainWindow();

    /**
     * @brief initWin，初始化
     */
    void initWin();
    /**
     * @brief selectImg，打开文件框，选择一张本地图片并矫正
     */
    void selectImgAndUndistort();
    /**
     * @brief createNewSetting，创建新的配置文件夹
     */
    void createNewSetting();

    /**
     * @brief setFileChanged，选择的配置文件改变时，读入新的配置文件
     */
    void setFileChanged();

    /**
     * @brief readSetToUi，把set中的属性读出来显示到ui上
     * @param set
     */
    void readSetToUi(const Settings& set);

    /**
     * @brief writeSetFromUi，把ui中的配置信息写入到set中，并且保存成xml文件
     * @param set
     */
    void writeSetFromUi();

    /**
     * @brief eventFilter，重写按键按下事件
     * @param watched
     * @param event
     * @return
     */
    bool eventFilter(QObject* watched, QEvent* event);

    /**
     * @brief acquireImgs，采集标定图像
     */
    void acquireImgs();

private:
    Ui::MainWindow *ui;

signals:
    /**
     * @brief sg_Cal，标定信号
     * @param argc
     * @param argv
     */
    void sg_Cal(int argc, char** argv);
    /**
     * @brief sg_DoCal，矫正图像信号
     * @param path
     */
    void sg_DoCal(string path);

public slots:
    /**
     * @brief txbTextChanged，textBox内容改变对应的槽函数
     * @param str
     */
    void txbTextChanged(const QString& str);
    /**
     * @brief cboxTextChanged，combox内容改变槽函数
     * @param str
     */
    void cboxTextChanged(const QString& str);
    /**
     * @brief ckboxStateChanged，checkbox状态改变槽函数
     * @param i
     */
    void ckboxStateChanged(int i);

};

static inline Qt::CheckState getCkSt(const bool state) {
    return state ? Qt::Checked : Qt::Unchecked;
}

static inline bool getBool(const Qt::CheckState state) {
    return state == Qt::Checked ? true : false;
}

#endif // MAINWINDOW_H
